﻿namespace FFF.Test.DataAccess.Framework.Configuration
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Security.Claims;
    using System.Text;
    using Abp.Dependency;
    using AutoMapper.QueryableExtensions;
    using Castle.Core.Resource;
    using JetBrains.Annotations;
    using Microsoft.AspNetCore.Http;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata;
    using Newtonsoft.Json;
    using FFF.Test.Entity.CF.View;
    using FFF.Test.Entity.Demo.View;
    using FFF.Test.Entity.Framework.Entity;
    using FFF.Test.Entity.Framework.View;
    using FFF.Test.Entity.FW.View;
    using FFF.Test.Util.Consts;
    using Ydm.QueryFilter.Core;

    /// <summary>
    /// 过滤器的配置
    /// </summary>
    public static class DbFilterConfiguration
    {
        private static readonly object Obj = new object();

        /// <summary>
        /// builder为了过滤来使用
        /// </summary>
        public static ModelBuilder ModelBuilder { get; set; }

        /// <summary>
        /// 初始化全局的过滤
        /// </summary>
        /// <param name="entityType">过滤</param>
        /// <param name="modelBuilder">builder</param>
        public static void InitGobalFilter(IMutableEntityType entityType, ModelBuilder modelBuilder)
        {
            if (modelBuilder == null)
            {
                return;
            }

            IEnumerable<IMutableProperty> props = entityType.GetProperties();

            if (props.Any(x => x.Name == "IsDeleted"))
            {
                ParameterExpression parameter = Expression.Parameter(entityType.ClrType, "e");
                byte defaultValue = 0;
                BinaryExpression body = Expression.Equal(
                    Expression.Call(typeof(EF), nameof(EF.Property), new[] { typeof(byte) }, parameter, Expression.Constant("IsDeleted")),
               Expression.Constant(defaultValue));

                // var body2 = Expression.Equal(
                //     Expression.Call(typeof(EF), nameof(EF.Property), new[] { typeof(byte?) }, parameter, Expression.Constant("IsDeleted")),
                // Expression.Constant(null, typeof(byte?)));
                // var body3 = Expression.Or(body1, body2);

                if (entityType.ClrType.BaseType == typeof(BaseView<Guid>))
                {
                    modelBuilder.Query(entityType.ClrType).HasQueryFilter(Expression.Lambda(body, parameter));
                }
                else if (entityType.ClrType.BaseType == typeof(BaseEntity<Guid>))
                {
                    modelBuilder.Entity(entityType.ClrType).HasQueryFilter(Expression.Lambda(body, parameter));
                }
            }

            //foreach (var prop in props)
            //{
            //    if (prop.Name == "IsDeleted")
            //    {
            //        var parameter = Expression.Parameter(entityType.ClrType, "e");
            //        byte defaultValue = 0;
            //        var body1 = Expression.Equal(
            //            Expression.Call(typeof(EF), nameof(EF.Property), new[] { typeof(byte) }, parameter, Expression.Constant("IsDeleted")),
            //       Expression.Constant(defaultValue));

            //        // var body2 = Expression.Equal(
            //        //     Expression.Call(typeof(EF), nameof(EF.Property), new[] { typeof(byte?) }, parameter, Expression.Constant("IsDeleted")),
            //        // Expression.Constant(null, typeof(byte?)));
            //        // var body3 = Expression.Or(body1, body2);

            //        if (entityType.Name.ToLower().Contains("view"))
            //        {
            //            modelBuilder.Query(entityType.ClrType).HasQueryFilter(Expression.Lambda(body1, parameter));
            //        }
            //        else
            //        {
            //            modelBuilder.Entity(entityType.ClrType).HasQueryFilter(Expression.Lambda(body1, parameter));
            //        }
            //    }
            //}
        }

        /// <summary>
        /// 初始化context的过滤
        /// </summary>
        /// <param name="resolver">依赖注入对象</param>
        /// <param name="db">context对象</param>
        public static void InitContextFilter(IIocResolver resolver, MyDbContext db)
        {
            if (resolver == null)
            {
                return;
            }

            HttpContext httpContext = resolver.Resolve<IHttpContextAccessor>().HttpContext;

            // 获取用户的登录信息
            if (httpContext == null)
            {
                return;
            }

            // 设置公司的全局过滤
            HeadBuInfo buInfo = null;
            string buInfoStr = httpContext.User.Claims.FirstOrDefault(d => d.Type == ClaimTypes.Webpage)?.Value;
            if (buInfoStr != null)
            {
                buInfo = JsonConvert.DeserializeObject<HeadBuInfo>(buInfoStr);
            }

            if (buInfo != null)
            {
                if (buInfo.BuGUID != null)
                {
                    #region Demo
                    // 根据公司GUID过滤
                    db.Filter<ViewDemoStudentTe>(q => q.Where(x => x.BuUnitGUID == buInfo.BuGUID));
                    db.Filter<ViewDemoClass>(q => q.Where(x => x.BuUnitGUID == buInfo.BuGUID));
                    db.Filter<ViewDemoStudentEdit>(q => q.Where(x => x.BuUnitGUID == buInfo.BuGUID));
                    db.Filter<ViewDemoSchoolTe>(q => q.Where(x => x.BuUnitGUID == buInfo.BuGUID));
                    #endregion
                }

                // 根据企业过滤
                if (buInfo.CompanyGUID != null)
                {
                    #region FW
                    db.Filter<ViewCFBizParamSet>(q => q.Where(x => x.TenantId == buInfo.CompanyGUID));
                    db.Filter<ViewFWUser>(q => q.Where(x => x.TenantId == buInfo.CompanyGUID));
                    db.Filter<ViewFWBuUnit>(q => q.Where(x => x.TenantId == buInfo.CompanyGUID));
                    db.Filter<ViewFWStandardRole>(q => q.Where(x => x.TenantId == buInfo.CompanyGUID));
                    #endregion
                }

            }

            // 设置用户的过滤
            ViewFWUser userInfo = httpContext.Session.GetUserInfo();
            if (userInfo != null)
            {
                if (userInfo.UserIsAdmin != 1)
                {
                    // 过滤Application
                    db.Filter<ViewFWApplication>(q => q.Where(x => userInfo.AplicationGUIDs.Contains(x.Id)));

                    // 过滤module
                    db.Filter<ViewFWModule>(q => q.Where(x => userInfo.ModuleGUIDs.Contains(x.Id)));
                    db.Filter<ViewFWApplication2Module>(q => q.Where(x => userInfo.ModuleGUIDs.Contains(x.ModuleGUID ?? Guid.Empty)));

                    // 过滤function
                    db.Filter<ViewFWFunction>(q => q.Where(x => userInfo.FunctionGUIDs.Contains(x.Id)));

                    // 过滤门店
                    db.Filter<ViewFWBuUnit>(q => q.Where(x => userInfo.BuUnitNewGUIDs.Contains(x.Id.ToString())));

                    if (buInfo.CompanyGUID != null)
                    {
                        db.Filter<ViewFWAction2User>(q => q.Where(x => db.ViewFWCompany2Action.Any(m => m.ActionGUID == x.ActionGUID && m.CompanyGUID == buInfo.CompanyGUID)));
                        db.Filter<ViewFWAction>(q => q.Where(x => db.ViewFWCompany2Action.Any(m => m.ActionGUID == x.Id && m.CompanyGUID == buInfo.CompanyGUID)));
                    }
                }

            }
        }

        ///// <summary>
        ///// 初始化Query
        ///// </summary>
        ///// <param name="query">query对象</param>
        ///// <param name="resolver">依赖注入容器</param>
        ///// <typeparam name="TQuery">query类型</typeparam>
        ///// <returns>过滤规则</returns>
        //public static bool InitTQuery<TQuery>(TQuery query, IIocResolver resolver)
        //{
        //    if (resolver == null)
        //    {
        //        return true;
        //    }

        //    var httpContext = resolver.Resolve<IHttpContextAccessor>().HttpContext;

        //    // 获取用户的登录信息
        //    if (httpContext == null)
        //    {
        //        return true;
        //    }

        //    var userInfo = httpContext.Session.GetUserInfo();
        //    if (userInfo != null)
        //    {
        //        if ((userInfo.IsAdmin ?? 0) != 1 && userInfo.UserType != MyUserUserTypeEnum.信息平台)
        //        {
        //            return EF.Property<Guid?>(query, "RepairBusinessGUID") == userInfo.RepairBusinessGUID;
        //        }

        //    }

        //    return true;
        //}

        ///// <summary>
        ///// 初始化Query
        ///// </summary>
        ///// <param name="resolver">依赖注入容器</param>
        ///// <typeparam name="TQuery">query类型</typeparam>
        ///// <returns>过滤规则</returns>
        //public static Expression<Func<TQuery, bool>> InitTQuery<TQuery>(IIocResolver resolver)
        //{
        //    Expression<Func<TQuery, bool>> func = queryEntity => MyInitQuery(queryEntity, resolver);
        //    if (resolver == null)
        //    {
        //        return func;
        //    }

        //    var httpContext = resolver.Resolve<IHttpContextAccessor>().HttpContext;

        //    // 获取用户的登录信息
        //    if (httpContext == null)
        //    {
        //        return func;
        //    }

        //    var userInfo = httpContext.Session.GetUserInfo();
        //    if (userInfo != null)
        //    {
        //        if ((userInfo.IsAdmin ?? 0) != 1 && userInfo.UserType != MyUserUserTypeEnum.信息平台)
        //        {
        //            func = queryEntity => EF.Property<Guid?>(queryEntity, "RepairBusinessGUID") == userInfo.RepairBusinessGUID;
        //            return func;
        //        }

        //    }

        //    return func;
        //}

        ///// <summary>
        ///// 初始化Query
        ///// </summary>
        ///// <param name="repairBusinessGUID">供应商GUID</param>
        ///// <returns>过滤规则</returns>
        //public static Guid? GetGUID(Guid? repairBusinessGUID)
        //{
        //    return repairBusinessGUID;
        //}

        ///// <summary>
        ///// 初始化Query
        ///// </summary>
        ///// <param name="resolver">依赖注入容器</param>
        ///// <param name="entityType">querytype的类型</param>
        ///// <returns>过滤规则</returns>
        //public static Guid? GetGUID([NotNull] IIocResolver resolver, IMutableEntityType entityType)
        //{
        //    var parameter = Expression.Parameter(entityType.ClrType, "e");
        //    Guid? repairBusinessGUID = EF.Property<Guid?>(entityType.ClrType, "RepairBusinessGUID");

        //    // Expression.Call(typeof(EF), nameof(EF.Property), new[] { typeof(Guid?) }, parameter, Expression.Constant("RepairBusinessGUID")).Method
        //    var httpContext = resolver.Resolve<IHttpContextAccessor>().HttpContext;
        //    var userInfo = httpContext.Session.GetUserInfo();
        //    if (userInfo != null)
        //    {
        //        if ((userInfo.IsAdmin ?? 0) != 1 && userInfo.UserType != MyUserUserTypeEnum.信息平台)
        //        {
        //            repairBusinessGUID = userInfo.RepairBusinessGUID;
        //        }
        //    }

        //    return repairBusinessGUID;
        //}

        //private IQueryable<T> ApplyTenantFilter<T>(IQueryable<T> source) where T : IHasTenant
        //   => source.Where(e => e.TenantId == _tenantId);

        ///// <summary>
        ///// 初始化Query
        ///// </summary>
        ///// <param name="query">query对象</param>
        ///// <param name="resolver">依赖注入容器</param>
        ///// <typeparam name="TQuery">query类型</typeparam>
        ///// <returns>过滤规则</returns>
        //public static Expression<bool> MyInitQuery<TQuery>(IIocResolver resolver)
        //{
        //    if (resolver == null)
        //    {
        //        return true;
        //    }

        //    var httpContext = resolver.Resolve<IHttpContextAccessor>().HttpContext;

        //    // 获取用户的登录信息
        //    if (httpContext == null)
        //    {
        //        return true;
        //    }

        //    var userInfo = httpContext.Session.GetUserInfo();
        //    if (userInfo != null)
        //    {
        //        if ((userInfo.IsAdmin ?? 0) != 1 && userInfo.UserType != MyUserUserTypeEnum.信息平台)
        //        {
        //            return EF.Property<Guid?>(query, "RepairBusinessGUID") == userInfo.RepairBusinessGUID;
        //        }
        //    }

        //    return true;

        //}
    }
}